#ifndef F_CPU
#define F_CPU 16000000UL
#endif

//Common
#include <util/delay.h>

//LCD/Touch
#include "lcd.h"
#include "touch.h"

//System Libraries
#include "int.h"
#include "config.h"
#include "system.h"

/*																					   */
/* ---------- GUI INSTRUCTIONS ------------------------------------------------------- */
/*
	/* CONSTANTS
	 * 
	*/

	/*
	 * Writing variables to screen with the help of streams
	 * char string[40];	==> global var
	 * sprintf(string, "Value of my variable: %d", yourVariable);
	 * LCD_write_english_string(POSX ,POSY, string, FONT_COLOR, BG_COLOR);
	 * or
	 * active_line = 0; ==> which line to write in
	 * GUI_writeLine(string, FONT_COLOR);
	*/
/*																					   */
/* ---------- GUI INSTRUCTIONS END---------------------------------------------------- */
/*																					   */


extern volatile uint8 touch_int_flag;
extern volatile uint8 time_changed_flag;

// RTC-I2C-Adress
#define DevDS1307	0xD0
// Stepper-I2C-Adress
#define DevTMC222	0xC0

int main(void) {

	init();

	//Run operating system
	uint8 posY, fill_height, i;
	uint16 posX, status_color;

	//Infinite outer loop, will never be left
	while(1) {

		LCD_clear(BLACK);
		GUI_setHeader("Main screen", HEADER_MODE_CLOCK);

		posX = MARGIN_LEFT;

		//Render slot menu
		for(i=0; i<NUMBER_SLOTS; i++) {
			fill_height = (uint8) allSlotValues[i].fill_level/100.0*SLOT_HEIGHT;
			posY = GUI_getStartingPos() + SLOT_HEIGHT - fill_height;

			if(allSlotValues[i].fill_level < allSlotValues[i].dose) 					status_color = RED;
			else if(((uint8) (allSlotValues[i].fill_level/allSlotValues[i].dose)) == 1) status_color = YELLOW;
			else 																		status_color = GREEN;

			GUI_drawBox(posX, posY, SLOT_WIDTH, fill_height, status_color);
		
			sprintf(string, "%dml", (uint8) allSlotValues[i].fill_level);
			LCD_write_english_string(posX + 3, posY - 15, string, status_color, BLACK);

			posX += SLOT_WIDTH + SLOT_PADDING_LEFT;
		}

		//Show times till next dose
		GUI_showTimeLeft();

		struct xy_pos result;
		result.x = 0;
		result.y = 0;

		show_touch(&result);
		enableInterrupt();
		touch_int_flag = 0;

		uint8 render = 0;

		//While render equals true (1) => wait for input => no need to render screen again
		while(!render) {

			//Rendering depends on if injection needed (injection shows popup => screen messed up after injection)
			render = checkIfInjectionNeeded();

			//Timer interrupt happened, refresh clock and times left till next dose
			if(time_changed_flag) {
				GUI_showClock();
				GUI_showTimeLeft();
				time_changed_flag = 0;
			}

			//Touch interrupt happened, evaluate touch input
			if(touch_int_flag) {
				show_touch(&result);

				//Determine which section was clicked
				if((result.y > GUI_getStartingPos()) && (result.y < (GUI_getStartingPos() + SLOT_HEIGHT))) {
					
					//Slot clicked, calculate slot
					uint8 selected_slot = (result.x - MARGIN_LEFT)/(SLOT_WIDTH + SLOT_PADDING_LEFT);

					if((selected_slot >= 0) && (selected_slot < NUMBER_SLOTS)) {
						GUI_screen_params(selected_slot);
						render = 1;
					}

				} else if(result.y < HEADER_HEIGHT) {

					//Header clicked, clock or date modification?
					if(result.x > MARGIN_LEFT_CLOCK) {

						//Clock clicked, show keyboard for setting the clock
						int8 input_keyboard[4];

						GUI_showKeyboard("Please adjust the time", KB_MODE_TIME, input_keyboard);
						if(input_keyboard[0] != HEADER_BACK_BTN_VALUE) {
							setTime(input_keyboard[0] * 10 + input_keyboard[1], input_keyboard[2] * 10 + input_keyboard[3]);
						}

					} else if(result.x > MARGIN_LEFT_DATE) {

						//Show keyboard in date mode
						int8 input_keyboard[6];

						GUI_showKeyboard("Please enter the date", KB_MODE_DATE, input_keyboard);
						if(input_keyboard[0] != HEADER_BACK_BTN_VALUE) {
							setDate(input_keyboard[0]*10 + input_keyboard[1], input_keyboard[2]*10 + input_keyboard[3], input_keyboard[4]*10 + input_keyboard[5]);
						}

					}

					render = 1;

				} else if(result.y > (OFFSET_HEIGHT - LINE_HEIGHT - MARGIN_TOP)) {
					GUI_showErrorLog();
					render = 1;
				}
			}
		}

	} //END infinite outer loop	

}

